package com.slt.developkitweb.controler.company;

//import com.cmdi.b2bjoy.common.cache.CacheObject;
import com.cmdi.b2bjoy.common.cache.CacheObject;
import com.slt.developkitweb.annotation.ShowAPI;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author shalongteng
 * @Date 2023/11/17 9:39
 * @Description 测试travelapi 从redis取出数据乱码问题
 * <p>
 * 对于 Spring Boot 2.x：
 * spring.redis.database=0
 * spring.redis.host=localhost
 * spring.redis.port=16379
 * spring.redis.password=mypass
 * spring.redis.timeout=60000
 * <p>
 * <p>
 * 对于 Spring Boot 3.x，我们需要设置以下属性：
 * spring.data.redis.database=0
 * spring.data.redis.host=localhost
 * spring.data.redis.port=16379
 * spring.data.redis.password=mypass
 * spring.data.redis.timeout=60000
 **/
@Slf4j
@ShowAPI
@Api(tags = "商旅接口")
@RestController
@RequestMapping("/travel")
public class TravelRedisController {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 默认返回一万行日志
     */
    @GetMapping("getFromRedis")
    @Operation(summary = "测试redis乱码问题", description = "travelapi 从redis取出来了数据，回乱码，无法反序列化成java实体")
    @Parameter
    public Object getFromRedis() {
        CacheObject<Object> cacheObject1 = new CacheObject<>();
        ValueOperations redisCache = redisTemplate.opsForValue();

        Object airportCodeMap = redisCache.get("BASIC_DATA_MAP");
        System.out.println(airportCodeMap.getClass().getName());
        System.out.println(airportCodeMap.getClass().getClassLoader());

        System.out.println(cacheObject1.getClass().getName());
        System.out.println(cacheObject1.getClass().getClassLoader());

        CacheObject cacheObject = (CacheObject) airportCodeMap;
        System.out.println(cacheObject.getObject());

        return null;
    }

    /**
     * @Author shalongteng
     * @Date 2024/2/4 11:18
     * @Description 流水线处理，批处理
     * 普通命令：一个连接，处理一个命令
     * pipeline：一个连接 ，处理多个命令。
     **/
    @GetMapping("testRedisPipeLine")
    @Operation(summary = "测试redis pipeline使用", description = "travelapi 从redis取出来了数据，回乱码，无法反序列化成java实体")
    @Parameter
    public Object testRedisPipeLine() {
        ArrayList<Object> listResult = new ArrayList<>();
        CacheObject cacheObject3 = (CacheObject) redisTemplate.opsForValue().get("SYS_CONFIG_MAP");


        List<Object> resultList = redisCallBackHandler();
        List<Object> resultList2 = redisCallBackHandler2();
        if(resultList.get(0) instanceof CacheObject){
            System.out.println("000000000");
        }
        if(resultList2.get(0) instanceof CacheObject){
            System.out.println("000000000");
        }
        CacheObject cacheObject = (CacheObject) resultList.get(0);
        Object object = cacheObject.getObject();

        System.out.println(5);
        return 5;
    }

    private List<Object> redisCallBackHandler() {
        //这里获取String类型的序列化器
        RedisSerializer serializer = new JdkSerializationRedisSerializer();
        //第二个参数是指定结果反序列化器，用于反序列化管道中读到的数据，不是必传，
        //如果不传，则使用自定义RedisTemplate的配置，如果没有自定义，则使用RedisTemplate默认的配置（JDK反序列化）
        List<Object> list = redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                //这里bytes只会获取到null，因为这里get操作只是放在管道里面，并没有真正执行，所以获取不到值
                connection.get("NOT_SALE_CABIN".getBytes());
                //executePipelined 这个方法需要返回值为null，不然会抛异常，
                return null;
            }
        }, serializer);

        return list;
    }


    private List<Object> redisCallBackHandler2() {
        //这里获取String类型的序列化
        RedisSerializer redisSerializer = redisTemplate.getDefaultSerializer();
        //第二个参数是指定结果反序列化器，用于反序列化管道中读到的数据，不是必传，
        //如果不传，则使用自定义RedisTemplate的配置，
        //如果没有自定义，则使用RedisTemplate默认的配置（JDK反序列化）
        List list = redisTemplate.executePipelined(new SessionCallback<Object>() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                //这里o只会获取到null，因为这里get操作只是放在管道里面，并没有真正执行，所以获取不到值
                CacheObject cacheObject = (CacheObject) operations.opsForValue().get("NOT_SALE_CABIN");
                //executePipelined 这个方法需要返回值为null，不然会抛异常，
                //这一点可以查看executePipelined源码
                return null;
            }
        }, redisSerializer);
        return list;
    }
}
